ReactWaves
React component wrapper for Wavesurfer.js
Background
This component was originally based off of the work done in react-wavesurfer by @mspae (and others). After wavesurfer-js released version 2, and the react-wavesurfer projected became unmaintained, I decided that it was safer to start my own version that I had better control over.
Version 4.x
To align this component nicer with the base wavesurfer.js project, I decided to skip version 2 and go straight to version 3. With wavesurfer now on version 4, we have made the necessary updates and are now also on v4.
Issues
Please report any issues you encounter and I will try my best to get them fixed.
Examples
Here's a basic demo and the example code include in this repo:
Here's an example of the personal project where I'm using this code:
Install
npm install @dschoon/react-waves
or
yarn add @dschoon/react-waves
Basic Example
import React from "react";
import ReactWaves from "@dschoon/react-waves";
import africa from "../audio/africa.mp3";
export default class BasicExample extends React.Component {
state = {
playing: false,
};
render() {
return (
<div className={"container example"}>
<div
className="play button"
onClick={() => {
this.setState({ playing: !this.state.playing });
}}
>
{!this.state.playing ? "▶" : "■"}
</div>
<ReactWaves
audioFile={africa}
className={"react-waves"}
options={{
barHeight: 2,
cursorWidth: 0,
height: 200,
hideScrollbar: true,
progressColor: "#EC407A",
responsive: true,
waveColor: "#D1D6DA",
}}
volume={1}
zoom={1}
playing={this.state.playing}
/>
</div>
);
}
}
Available Props
props = {
playing: PropTypes.bool,
pos: PropTypes.number,
audioFile: (props, propName, componentName) => {
const prop = props[propName];
if (
prop &&
typeof prop !== "string" &&
!(prop instanceof window.Blob) &&
!(prop instanceof window.File)
) {
return new Error(`Invalid ${propName} supplied to ${componentName}
expected either string or file/blob`);
}
return null;
},
mediaElt: PropTypes.oneOfType([
PropTypes.string,
PropTypes.instanceOf(window.HTMLElement),
]),
audioPeaks: PropTypes.array,
volume: PropTypes.number,
zoom: PropTypes.number,
onPosChange: PropTypes.func,
children: PropTypes.oneOfType([PropTypes.element, PropTypes.array]),
options: PropTypes.shape({
audioRate: PropTypes.number,
audioContext: PropTypes.object,
audioScriptProcessor: PropTypes.object,
autoCenter: PropTypes.bool,
backend: PropTypes.oneOf([
"WebAudio",
"MediaElement",
"MediaElementWebAudio",
]),
barGap: positiveIntegerProptype,
barHeight: positiveIntegerProptype,
barRadius: positiveIntegerProptype,
barWidth: (props, propName, componentName) => {
const prop = props[propName];
if (prop !== undefined && typeof prop !== "number") {
return new Error(`Invalid ${propName} supplied to ${componentName}
expected either undefined or number`);
}
return null;
},
closeAudioContext: PropTypes.bool,
cursorColor: PropTypes.string,
cursorWidth: positiveIntegerProptype,
fillParent: PropTypes.bool,
forceDecode: PropTypes.bool,
height: positiveIntegerProptype,
hideScrollbar: PropTypes.bool,
interact: PropTypes.bool,
loopSelection: PropTypes.bool,
maxCanvasWidth: positiveIntegerProptype,
mediaControls: PropTypes.bool,
mediaType: PropTypes.oneOf(["audio", "video"]),
minPxPerSec: positiveIntegerProptype,
normalize: PropTypes.bool,
partialRender: PropTypes.bool,
pixelRatio: PropTypes.number,
progressColor: PropTypes.string,
removeMediaElementOnDestroy: PropTypes.bool,
renderer: PropTypes.object,
responsive: PropTypes.bool,
scrollParent: PropTypes.bool,
skipLength: PropTypes.number,
splitChannels: PropTypes.bool,
waveColor: PropTypes.oneOfType([
PropTypes.string,
PropTypes.instanceOf(window.CanvasGradient),
]),
xhr: PropTypes.object,
}),
spectrogramOptions: PropTypes.object,
timelineOptions: PropTypes.object,
};
License
MIT © Dan Schoonmaker (github)
Last Updated: November 11th, 2020